package com.yanqu.road.entity.buildDaoUtil;

import com.yanqu.road.entity.FieldTypeAnnotation;
import com.yanqu.road.entity.log.cross.newMonopolyMarket.log.NewMonopolyMarketOfficeRobLogData;
import com.yanqu.road.utils.string.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BuildLogSql {

    // Map<java类型 , 数据库类型java.sql.Types>
    private static Map<Class, String> typeMap = new HashMap<>();

    static {
        typeMap.put(boolean.class, "BOOLEAN");
        typeMap.put(short.class, "SMALLINT");
        typeMap.put(int.class, "INTEGER");
        typeMap.put(long.class, "BIGINT");
        typeMap.put(String.class, "VARCHAR");
        typeMap.put(BigInteger.class, "VARCHAR");
        typeMap.put(BigDecimal.class, "VARCHAR");
        typeMap.put(Date.class, "TIMESTAMP");
    }

    public static void main(String[] args) {
        Class<NewMonopolyMarketOfficeRobLogData> clz = NewMonopolyMarketOfficeRobLogData.class;

        String tableName = "";
        String className = clz.getSimpleName();
        List<String> fieldNames = new ArrayList<>();
        List<String> fieldTypes = new ArrayList<>();

        // 获取表名
        if (clz.isAnnotationPresent(FieldTypeAnnotation.class)) {
            tableName = clz.getAnnotation(FieldTypeAnnotation.class).tableName();
        }

        // 获取属性
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(FieldTypeAnnotation.class)) {
                // 字段名
                fieldNames.add(field.getName());
                // 类型String
                fieldTypes.add(typeMap.getOrDefault(field.getType(), "tmp_type"));
            }
        }

        // 组装问号
        String tmpValue = "";
        for (int i = 0; i < fieldNames.size(); i++) {
            tmpValue = tmpValue + "?,";
        }
        if (tmpValue.length() > 0) {
            tmpValue = tmpValue.substring(0, tmpValue.length() - 1);
        }

        // sql语句
        String sql = "INSERT INTO " + tableName
                + "(" + StringUtils.listToString(fieldNames, ",") + ") "
                + "VALUES(" + tmpValue + ")";

        // 批量插入方法
        StringBuilder sb = new StringBuilder();
        sb.append("public boolean add" + className + "List(List<" + className + "> list) {");
        newLine(sb);
        sb.append("boolean result = false;");
        newLine(sb);
        sb.append("getDb().setConnName(DbNameStrategy.getLogDb());");
        newLine(sb);
        sb.append("String sql = \"" + sql + "\";");
        newLine(sb);
        sb.append("List<Map<Integer, DbParameter>> mapList = new ArrayList<>();");
        newLine(sb);
        sb.append("for (" + className + " data : list) {");
        newLine(sb);
        sb.append("Map<Integer, DbParameter> para = new HashMap<>();");
        newLine(sb);
        sb.append("int i = 1;");
        newLine(sb);
        for (int i = 0; i < fieldNames.size(); i++) {
            sb.append("para.put(i++, new DbParameter(Types." + fieldTypes.get(i) + ", data.get" + firstUpper(fieldNames.get(i)) + "()));");
            newLine(sb);
        }
        sb.append("mapList.add(para);");
        newLine(sb);
        sb.append("}");
        newLine(sb);
        sb.append("if (getDb().executeBatchQuery(sql, mapList) > -1) {");
        newLine(sb);
        sb.append("result = true;");
        newLine(sb);
        sb.append("}");
        newLine(sb);
        sb.append("return result;");
        newLine(sb);
        sb.append("}");
        newLine(sb);

        // 输出结果
        System.out.println(sb.toString());
    }

    // 换行
    private static void newLine(StringBuilder sb) {
        sb.append("\r\n");
    }

    // 首字母大写
    private static String firstUpper(String fieldName) {
        if (fieldName == null || fieldName.length() == 0) {
            return "";
        }
        return fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    }

}
